﻿using Castle.DynamicProxy;
using CNKI.TPI.Web.Admin.IDAO;
using CNKI.TPI.Web.Base;
using CNKI.TPI.Web.Search.IBLL;
using CNKI.TPI.Web.Search.IDAO;
using CNKI.TPI.Web.Search.Model;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CNKI.TPI.Web.Admin.Model;
using System.Web;
using System.Security.Cryptography;

namespace CNKI.TPI.Web.Search.BLL
{


    public class SubmitService : BaseService, ISubmitService
    {
        private IUserDBDAO userDBDao = null;
        private ICategoryDAO categoryDAO = null;
        private IHomeConfigDAO homeConfigDAO = null;

        public SubmitService(IUserDBDAO userDBDao, ICategoryDAO categoryDAO, IHomeConfigDAO homeConfigDAO)
        {
            this.userDBDao = this.generator.CreateInterfaceProxyWithTarget<IUserDBDAO>(userDBDao, new IInterceptor[] { new LogInterceptor() });
            this.categoryDAO = this.generator.CreateInterfaceProxyWithTarget<ICategoryDAO>(categoryDAO, new IInterceptor[] { new LogInterceptor() });
            this.homeConfigDAO = this.generator.CreateInterfaceProxyWithTarget<IHomeConfigDAO>(homeConfigDAO, new IInterceptor[] { new LogInterceptor() });
        }

        public IList<SYS_CMS_OPTION> GetSubmitDBList(int Flag)
        {
            return userDBDao.GetSubmitDBList(Flag);
        }

        public IList<SYS_CMS_SUBMIT> GetSubmitConfig(string dbCode)
        {
            return userDBDao.GetSubmitConfig(dbCode);
        }

        public SYS_CMS_SUBMIT GetSubmitConfig(string dbCode, string fieldname, SubmitFieldType fieldType)
        {
            SYS_CMS_SUBMIT result = null;
            IList<SYS_CMS_SUBMIT> contentList = userDBDao.GetSubmitConfig(dbCode, fieldname, fieldType);
            if (contentList != null && contentList.Count > 0)
            {
                result = contentList[0];
            }
            return result;
        }

        public bool IsOnlyOne(string strDbCode, int sysid, string strField, string strFieldValue)
        {
            bool result = true;
            try
            {
                DataTable dt = userDBDao.IsOnlyOne(strDbCode, strField, strFieldValue);
                if (dt != null)
                {
                    foreach (DataRow dr in dt.Rows)
                    {
                        if (int.Parse(dr[0].ToString()) != sysid)
                        {
                            result = false;
                            break;
                        }
                    }
                }

            }
            catch (Exception ex)
            {
                LogOpr.Error(ex.ToString());
            }
            return result;
        }

        public string GetPYHZList(string dbcode)
        {
            string result = null;
            try
            {
                Dictionary<string, string> dicPYHZs = new Dictionary<string, string>();//数据字典用来存储拼音汉字字段信息
                string strHzToPy = "";
                IList<SYS_CMS_HZTOPY> PYHZList = userDBDao.GetPYHZList(dbcode);
                if (PYHZList != null && PYHZList.Count > 0)
                {
                    strHzToPy = PYHZList[0].HZTOPY;
                    if (strHzToPy.IndexOf("###") >= 0)
                    {
                        string[] strArrHzToPy = strHzToPy.Split(new string[] { "###" }, StringSplitOptions.RemoveEmptyEntries);
                        for (int i = 0; i < strArrHzToPy.Length; i++)
                        {
                            string strTempHzToPy = strArrHzToPy[i].ToString();
                            string[] ArrHzTempToPy = strTempHzToPy.Split(new string[] { "->" }, StringSplitOptions.RemoveEmptyEntries);
                            dicPYHZs.Add(ArrHzTempToPy[0].ToString(), ArrHzTempToPy[1].ToString());
                        }
                    }
                    else
                    {
                        string[] ArrHzToPy = strHzToPy.Split(new string[] { "->" }, StringSplitOptions.RemoveEmptyEntries);
                        dicPYHZs.Add(ArrHzToPy[0].ToString(), ArrHzToPy[1].ToString());
                    }

                    System.Text.StringBuilder sb = new System.Text.StringBuilder(); ;
                    foreach (var item in dicPYHZs)
                    {
                        sb.Append(item.Key + "," + item.Value + ";");
                    }
                    strHzToPy = sb.ToString().TrimEnd(';');

                    result = strHzToPy;
                }
            }
            catch (Exception ex)
            {
                LogOpr.Error(ex.ToString());
            }
            return result; ;
        }

        public DataTable ExecuteSql(string sql)
        {
            return userDBDao.GetDataTableBySql(sql);
        }

        public DataTable GetMetaData(int dbID, int sysid, string fieldList)
        {
            DataTable dt = new DataTable();
            //检索
            DataSet ds = userDBDao.SingleSearch(dbID, fieldList + ",SYS_FLD_SECURITY,SYS_FLD_DIGITFILENAME", "(SYS_FLD_SYSID Eq '" + sysid + "')", "", "", 1, 1, PermissionOption.None, enableCache: false);
            if (ds != null && ds.Tables.Count > 0)
            {
                dt = ds.Tables[0];
            }
            return dt;
        }

        /// <summary>
        /// 计算文件MD5值
        /// </summary>
        /// <param name="path">文件路径</param>
        /// <returns></returns>
        private string FileToMD5(string path)
        {
            string strMd5 = "";
            try
            {
                using (System.IO.FileStream fs = new System.IO.FileStream(path, System.IO.FileMode.Open))
                {
                    System.Security.Cryptography.MD5CryptoServiceProvider md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
                    byte[] b = md5.ComputeHash(fs);
                    strMd5 = System.BitConverter.ToString(b).Replace("-", "");
                }
            }
            catch (Exception e)
            {
                LogOpr.Error(e.ToString());
            }
            return strMd5;
        }

        /// <summary>
        /// 计算MetaDoi值
        /// </summary>
        /// <param name="nRecid">记录编号</param>
        /// <returns></returns>
        private string MetaDoi(int nRecid, string strDbCode)
        {
            string strNewDoi = "";
            try
            {
                string strDOI = "";
                // 构造DOI字段的前面部分(DOI:TTKN.001.Ebook.EBOOKDB)
                IList<SYS_CMS_MEMBER_UNIT> DOI = userDBDao.GetMember_Unit();
                if (DOI != null)
                {
                    strDOI = DOI[0].DOIPREFIX + ":" + DOI[0].UNITSHOUXIE + "." + DOI[0].UNITCODE + ".";
                    int strDBType = categoryDAO.GetDatabaseByCode(strDbCode).DatabaseType;
                    string strDBTypeCode = homeConfigDAO.GetTemplateByID(strDBType).RESOURCECODE;
                    strDOI += strDBTypeCode + "." + strDbCode + "/";

                    // 插入记录的MetaID
                    string strTempNum = "";
                    for (int j = 0; j < 8 - nRecid.ToString().Length; j++)
                    {
                        strTempNum = "0" + strTempNum;
                    }

                    // 保存记录的其它信息（doi字段）
                    strNewDoi = strDOI + DateTime.Now.Year + strTempNum + nRecid;
                }
            }
            catch (Exception e)
            {
                LogOpr.Error(e.ToString());
            }
            return strNewDoi;
        }

        public int ProcessMetaDataFile(string dbcode, bool isUnicode, int nInsertRows, string resorceType, int contentType, int readOnline, int contentFlag, string filename, string filesize, string fileformat, string filepath, string digitfilename, int flag)
        {
            int nUpdate = 0;
            if (!String.IsNullOrEmpty(filename))
            {
                if (filename.IndexOf("|") >= 0)
                {
                    string[] ArrFileName = filename.Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries);
                    string[] ArrFileSize = filesize.Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries);
                    string[] ArrFileFormat = fileformat.Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries);
                    string[] ArrFilePath = filepath.Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries);
                    for (int i = 0; i < ArrFileName.Length; i++)
                    {
                        nUpdate = InsertUpdateMetaDataFile(dbcode, nInsertRows, resorceType, contentType, readOnline, contentFlag, ArrFilePath[i], ArrFileName[i], ArrFileSize[i], ArrFileFormat[i]);
                    }

                }
                else
                {
                    nUpdate = InsertUpdateMetaDataFile(dbcode, nInsertRows, resorceType, contentType, readOnline, contentFlag, filepath, filename, filesize, fileformat);
                }
            }

            //更新主表附件内容
            //更新主表附件内容
            if (flag == -1)
            {
                nUpdate = userDBDao.UpdateFileInfo(dbcode, filename, nInsertRows);
            }
            else
            {
                nUpdate = userDBDao.UpdateFileInfo(dbcode, digitfilename, nInsertRows);
            }
            return nUpdate;
        }

        public bool CheckFileExsit(int sysid, string dbcode, string fileName)
        {
            bool result = false;
            try
            {
                int count = userDBDao.GetFileCount(dbcode, fileName, sysid);
                if (count > 0)
                {
                    result = true;
                }
            }
            catch(Exception ex)
            {
                LogOpr.Error(ex.ToString());
            }
            return result;
        }

        private int InsertUpdateMetaDataFile(string dbcode, int nInsertRows, string resorceType, int contentType, int readOnline, int contentFlag, string filepath, string fileName, string fileSize, string fileFormat)
        {
            int nFileID = 0;
            int nIsExist = userDBDao.GetFileCount(dbcode, fileName);
            if (nIsExist > 0)
            {
                //更新附件表信息-上传时间
                nFileID = userDBDao.UpdateUploadFileDate(dbcode, fileName);
            }
            else
            {
                METADATA_FILE fileInfo = new METADATA_FILE();
                fileInfo.RECORDID = nInsertRows;
                fileInfo.RESOURCETYPE = resorceType;
                fileInfo.FORMAT = fileFormat;
                fileInfo.CONTENTTYPE = contentType;
                fileInfo.UPLOADTIME = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                fileInfo.FILENAME = fileName;
                fileInfo.FILESIZE = int.Parse(fileSize);
                fileInfo.MD5CODE = FileToMD5(filepath);
                fileInfo.READONLINE = readOnline;
                fileInfo.CONTENTFLAG = contentFlag;
                nFileID = userDBDao.InsertUploadFile(dbcode, fileInfo);

                if (nFileID > 0)
                {
                    //更新附件表信息-Doi与排序数
                    string strSortNum = nFileID.ToString();
                    string strMetaID = MetaDoi(nFileID, dbcode);
                    string strDOI = strMetaID + "." + resorceType + "." + fileFormat;
                    nFileID = userDBDao.UpdateUploadFileDOISortNo(dbcode, nFileID, strDOI, strSortNum);
                }
            }
            return nFileID;
        }

        public string DeleteFileInfo(string dbcode, string filename, string digitfilename, int sysid, string result, string strSavePath)
        {
            //删除附件表记录
            bool bl = userDBDao.DeleteFileInfo(dbcode, filename, sysid);
            if (bl)
            {
                //更新主表SYS_FLD_DIGITFILENAME字段信息
                digitfilename = StringHelper.removeStr(digitfilename, filename);

                int nUpdate = userDBDao.UpdateFileInfo(dbcode, digitfilename, sysid);
                if (nUpdate > 0)
                {
                    //删除实体附件 
                    //try
                    //{
                    //    System.IO.File.Delete(strSavePath);
                    //}
                    //catch
                    //{

                    //}
                    DeleteFile(strSavePath);
                    result = digitfilename;
                }
            }
            return result;
        }

        public int UpdateMetaFileLink(string dbcode, int oldRecID, int newRecID)
        {
            int result = 0;
            try
            {
                result = userDBDao.UpdateMetaFileLink(dbcode, oldRecID, newRecID);
                DataTable dt = userDBDao.GetMetaInfo(dbcode, oldRecID);
                result = userDBDao.UpdateMetaInfo(dbcode, newRecID, dt.Rows[0][0].ToString(), dt.Rows[0][1].ToString());
                result = 1;
            }
            catch(Exception ex)
            {
                LogOpr.Error(ex.ToString());
            }
            return result;
        }

        public DataTable GetDataBySql(string sql, int pageIndex, int pageSize, out int count)
        {
            DataTable dt = null;
            count = 0;
            try
            {
                dt = userDBDao.GetDataTableBySql(sql, pageIndex, pageSize, out count);
            }
            catch (Exception ex)
            {
                LogOpr.Error(ex.ToString());
            }
            return dt;
        }

        public bool SaveFile(HttpPostedFile file, string filePath)
        {
            bool result = false;
            try
            {
                string fileName = Md5(filePath);
                string srcFile = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + fileName;
                file.SaveAs(srcFile);
                result = userDBDao.SaveFile(srcFile, filePath);
                System.IO.File.Delete(srcFile);
            }
            catch (Exception ex)
            {
                LogOpr.Error(ex.ToString());
            }
            return result;
        }

        private string Md5(string content)
        {
            // 第三步：使用MD5加密
            MD5 md5 = MD5.Create();
            byte[] bytes = md5.ComputeHash(Encoding.UTF8.GetBytes(content));

            // 第四步：把二进制转化为大写的十六进制
            StringBuilder result = new StringBuilder();
            for (int i = 0; i < bytes.Length; i++)
            {
                result.Append(bytes[i].ToString("X2"));
            }
            return result.ToString();
        }

        public bool DeleteFile(string filePath)
        {
            bool result = false;
            try
            {
                result = userDBDao.DeleteFile(filePath);
            }
            catch (Exception ex)
            {
                LogOpr.Error(ex.ToString());
            }
            return result;
        }
    }
}
